import { Component, OnInit, ViewChild } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd/message';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { NzModalService } from 'ng-zorro-antd/modal';
import { storageDeliveryMethodArrs } from '../../xstorage-manage-pipes/storage-manage-z.pipe';
import { CommonService } from '../../../../services-common/common.service';
import { StorageCommonService } from '../../xstorage-manage-services/storage-common.service';
import { PermissionService } from '../../../../service/permission.service';
import { ExwarehousmanageService } from '../../xstorage-manage-services/exwarehous-manage.service';

@Component({
  selector: 'app-storage-exwarehous-operation',
  templateUrl: './storage-exwarehous-operation.component.html',
  styleUrls: ['./storage-exwarehous-operation.component.scss']
})
export class StorageExwarehousOperationComponent implements OnInit {
  // 路由缓存恢复时
  static updateCache: any = null;
  @ViewChild('followUpRef') followUpRef: any;

  searchOptions: any = [
    { type: 1, labelText: '出库单号', valueKey: 'deliveryNumber', value: '' },
    {
      type: 2,
      labelText: '出库仓库',
      valueKey: 'whId',
      value: [],
      multiple: true,
      notTostr: false,
      selectBindKey: { key: 'id', label: 'name' },
      selectOptions: [],
    }
  ];
  searchParams: any = {};

  outTypeOptions: any[] = []; // 出库类型options
  warehouseOptions: any[] = []; // 仓库Options
  logisticsOptions: any[] = []; // 物流Options

  tableParams: any = {
    loading: false,
    tableData: [],
    page: 1,
    pageSize: 20,
    total: 0
  };

  exportPickLoading = false;

  // 跟进 Modal
  initParams: any = {
    type: 4, // type 1、采购 2、SN 3、入库单 4、出库单
    relationInformation: ''
  };

  /**
   * 配送方式修改 Modal
   * ----------------------------------------------------------------
   */
  isDeliveryVisible = false;
  deliveryOptions: any[] = [...storageDeliveryMethodArrs];
  validateDeliveryForm!: FormGroup;
  modifyDeliveryLoading = false;

  /**
   * ----------------------------------------------------------------
   * table check
   * ---------------------------------------------------------------- 
   */

  checked = false;
  indeterminate = false;
  listOfCurrentPageData: readonly any[] = [];
  setOfCheckedId = new Set<number>();
  setOfCheckedArrs: any[] = [];

  updateCheckedSet(id: number, checked: boolean): void {
    if (checked) {
      let checkedItem = this.listOfCurrentPageData.find(ele => ele.id === id);
      let setIds = this.setOfCheckedArrs.map(m => m.id);

      this.setOfCheckedId.add(id);
      if (!setIds.includes(id)) {
        this.setOfCheckedArrs.push({...checkedItem});
      }
    } else {
      let deleteIndex = this.setOfCheckedArrs.findIndex(ele => ele.id === id);

      this.setOfCheckedId.delete(id);
      this.setOfCheckedArrs.splice(deleteIndex, 1);
    }
  }

  onItemChecked(id: number, checked: boolean): void {
    this.updateCheckedSet(id, checked);
    this.refreshCheckedStatus();
  }

  onAllChecked(value: boolean): void {
    this.listOfCurrentPageData.forEach(item => this.updateCheckedSet(item.id, value));
    this.refreshCheckedStatus();
  }

  onCurrentPageDataChange($event: readonly any[]): void {
    this.listOfCurrentPageData = $event;
    this.refreshCheckedStatus();
  }

  refreshCheckedStatus(): void {
    this.checked = this.listOfCurrentPageData.every(item => this.setOfCheckedId.has(item.id));
    this.indeterminate = this.listOfCurrentPageData.some(item => this.setOfCheckedId.has(item.id)) && !this.checked;
  }

  constructor(
    private msg: NzMessageService,
    private fb: FormBuilder,
    private modal: NzModalService,
    private commonService: CommonService,
    public permission: PermissionService,
    private storageCommonService: StorageCommonService,
    private services: ExwarehousmanageService
  ) { }

  ngOnInit(): void {
    this.loadOutTypeOptions();
    this.loadLogisticsData();
    this.loadStoreOptions();

    this.validateDeliveryForm = this.fb.group({
      isFreight: ['', [Validators.required]], // 运费承担
      deliveryMethod: ['', [Validators.required]], // 配送方式
      expressCode: [''], // 物流公司
      expressNo: [''], // 物流单号
      expressPrice: [''], // 运费
      deliverRemark: [''] // 发货备注
    });

    StorageExwarehousOperationComponent.updateCache = () => {
      this.loadTable();
    }
  }

  // 出库类型options
  async loadOutTypeOptions() {
    const res: any = await this.commonService.getDictList('outbound_type');
    this.outTypeOptions = res || [];
  }

  // 查询物流
  async loadLogisticsData() {
    const res: any = await this.commonService.getDictList('logistics_company');
    this.logisticsOptions = (res && res.length) ? res : [];
  }

  // 查询仓库Options
  async loadStoreOptions() {
    let params = {
      page: 1,
      pageSize: 1000
    }
    const {code, data, message}: any = await this.storageCommonService.getWarehouseList(params);
    if (code === 0) {
      this.warehouseOptions = data.records || [];
      this.setSearchOption(data.records, 'whId');
    } else {
      this.msg.error(message);
    }
  }

  async loadTable() {
    let params = {
      ...this.searchParams,
      state: '3,4,5', // 待打包、待出库、已出库
      page: this.tableParams.page,
      pageSize: this.tableParams.pageSize
    }
    this.tableParams.loading = true;
    const {code, data, message}: any = await this.services.getExwarehousList(params);
    this.tableParams.loading = false;

    if (code === 0) {
      this.tableParams.tableData = data.records || [];
      this.tableParams.total = data.total || 0;
    } else {
      this.msg.error(message);
    }
  }

  queryResetData(params: any) {
    this.searchParams = params;

    this.setOfCheckedId.clear();
    this.setOfCheckedArrs = [];
    this.tableParams.page = 1;
    this.loadTable();
  }

  // PageIndex Change
  onPageIndexChange(index: number) {
    this.tableParams.page = index;
    this.loadTable();
  }

  // PageSize Change
  onPageSizeChange(sizeNum: number) {
    this.tableParams.page = 1;
    this.tableParams.pageSize = sizeNum;
    this.loadTable();
  }

  /**
   * 修改配送方式 Modal
   * ----------------------------------------------------------------
   */
  showEditDeliveryModal() {
    this.msg.warning('当前功能暂未开放!!!');
    return
    
    if (!this.setOfCheckedId.size) {
      this.msg.warning('请先选择所需操作项');
      return
    }

    this.validateDeliveryForm.reset();
    this.isDeliveryVisible = true;
  }

  deliveryChange(val: any) {
    this.validateDeliveryForm.get('expressCode')?.setValue('');
    
    // (系统下单 | 手动下单), 物流公司 必填
    if ([1, 2].includes(val)) {
      this.validateDeliveryForm.get('expressCode')!.setValidators(Validators.required);
      this.validateDeliveryForm.get('expressCode')!.markAsDirty();
    } else {
      this.validateDeliveryForm.get('expressCode')!.clearValidators();
      this.validateDeliveryForm.get('expressCode')!.markAsPristine();
    }

    // 手动下单，物流单号 必填
    if (val === 2) {
      this.validateDeliveryForm.get('expressNo')!.setValidators(Validators.required);
      this.validateDeliveryForm.get('expressNo')!.markAsDirty();
    } else {
      this.validateDeliveryForm.get('expressNo')!.clearValidators();
      this.validateDeliveryForm.get('expressNo')!.markAsPristine();
    }

    ['expressCode', 'expressNo'].forEach(key => {
      this.validateDeliveryForm.get(key)!.updateValueAndValidity();
    })

    // 系统下单, 物流单号 & 运费 清空
    if (val === 1) {
      this.validateDeliveryForm.patchValue({
        expressNo: '',
        expressPrice: ''
      });
    }

    // 线下配送, 物流公司 & 物流单号 清空
    if (val === 3) {
      this.validateDeliveryForm.patchValue({
        expressCode: '',
        expressNo: ''
      });
    }

    // (动态设置)物流单号Input设置禁用
    if ([1, 3].includes(val)) {
      this.validateDeliveryForm.controls.expressNo.disable();
    } else {
      this.validateDeliveryForm.controls.expressNo.enable();
    }
  }

  async subEditDeliveryData() {
    if (this.validateDeliveryForm.valid) {
      let logisticsObj = this.logisticsOptions.find(ele => ele.content == this.validateDeliveryForm.value.expressCode);
      let params = {
        updateType: 1, // 1 修改配送信息 2 修改仓库 3 修改收货人信息 4 取消物流单
        delivery: {
          ...this.validateDeliveryForm.value,
          expressName: logisticsObj?.name || '', // 物流公司名
          expressNo: this.validateDeliveryForm.value.expressNo || '' // 物流单号
        },
        isBatch: 1,
        ids: [...this.setOfCheckedId]
      }
      // return
      this.modifyDeliveryLoading = true;
      const {code, data, message}: any = await this.services.updateDeliveryOrderInfoData(params);
      this.modifyDeliveryLoading = false;
  
      if (code === 0) {
        this.isDeliveryVisible = false;
        this.msg.success(data);
        this.setOfCheckedId.clear();
        this.setOfCheckedArrs = [];
        this.loadTable();
      } else {
        this.msg.error(message);
      }
    } else {
      Object.values(this.validateDeliveryForm.controls).forEach(control => {
        if (control.invalid) {
          control.markAsDirty();
          control.updateValueAndValidity({ onlySelf: true });
        }
      });
    }
  }

  /**
   * 通知出库 (type: 3) | 打包完成 (type: 4) | 确认出库 (type: 5) | 反审核 (type: 10) | 批量手动签收 (type: 6)
   * @param type 
   */
  async batchPperaInterface(type: number) {
    let params = {
      ids: [...this.setOfCheckedId],
      state: type,
      note: ''
    }

    const {code, data, message}: any = await this.services.auditExwarehousData(params);
    if (code === 0) {
      this.msg.success(data);
      this.loadTable();
    } else {
      this.msg.error(message);
    }
  }

  /**
   * 打包完成
   * @returns 
   */
  batchPackOver() {
    this.msg.warning('当前功能暂未开放!!!');
    return
    
    if (!this.setOfCheckedId.size) {
      this.msg.warning('请至少选择1个单据');
      return
    }

    this.modal.confirm({
      nzTitle: '提示',
      nzContent: '确认打包完成?',
      nzOkText: '确认',
      nzOkType: 'primary',
      nzOkDanger: true,
      nzOnOk: async () => {
        await this.batchPperaInterface(4);
        this.setOfCheckedId.clear();
        this.setOfCheckedArrs = [];
      },
      nzCancelText: '取消'
    });
  }

  /**
   * 确认出库
   * @returns 
   */
  batchConfirmCk() {
    this.msg.warning('当前功能暂未开放!!!');
    return
    
    if (!this.setOfCheckedId.size) {
      this.msg.warning('请至少选择1个单据');
      return
    }

    this.modal.confirm({
      nzTitle: '提示',
      nzContent: '该操作不可逆，确认后库存将会减少，确认已经出库?',
      nzOkText: '确认',
      nzOkType: 'primary',
      nzOkDanger: true,
      nzOnOk: async () => {
        await this.batchPperaInterface(5);
        this.setOfCheckedId.clear();
        this.setOfCheckedArrs = [];
      },
      nzCancelText: '取消'
    });
  }

  /**
   * 导出拣货信息
   * @returns 
   */
  exportPickData() {
    if (!this.setOfCheckedId.size) {
      this.msg.warning('请选择所需导出项');
      return
    }
    
    let isHasAccord = this.setOfCheckedArrs.some(item => item.state === 3);
    if (!isHasAccord) {
      this.msg.warning('请至少勾选一个待打包的单据');
      return
    }

    this.modal.confirm({
      nzTitle: '提示',
      nzContent: '确认导出拣货信息?',
      nzOkText: '确认',
      nzOkType: 'primary',
      nzOkDanger: true,
      nzOnOk: async () => {
        let params = {
          ids: [...this.setOfCheckedId].join(',')
        }
    
        this.exportPickLoading = true;
        const res: any = await this.services.exportExwarehousPickData(params);
        this.exportPickLoading = false;
    
        if (res.type === 'application/octet-stream') {
          this.commonService.downLoadBlobFile(res, '出库单拣货信息');
          this.setOfCheckedId.clear();
          this.setOfCheckedArrs = [];
        } else {
          this.msg.error('导出失败');
        }
      },
      nzCancelText: '取消'
    });
  }

  /**
   * 通知快递取件
   * @returns 
   */
  noticeTakeParts() {
    if (!this.setOfCheckedId.size) {
      this.msg.warning('请选择所需操作项');
      return
    }

    this.modal.confirm({
      nzTitle: '提示',
      nzContent: '确认通知快递取件?',
      nzOkText: '确认',
      nzOkType: 'primary',
      nzOkDanger: true,
      nzOnOk: async () => {
        let params = {
          ids: [...this.setOfCheckedId]
        }
    
        const {code, data, message}: any = await this.services.notifyPickupData(params);
        if (code === 0) {
          this.msg.success(data);
          this.setOfCheckedId.clear();
          this.setOfCheckedArrs = [];
          this.loadTable();
        } else {
          this.msg.error(message);
        }
      },
      nzCancelText: '取消'
    });
  }

  /**
   * other
   * ----------------------------------------------------------------
   */

  setSearchOption(array: Array<any>, val: string) {
    let temIndex = this.searchOptions.findIndex((item: any) => item.valueKey === val);
    this.searchOptions[temIndex].selectOptions = array || [];
  }

  // Filter Text
  filterText(arrs: Array<any>, keyVal: any, idKey: string) {
    let tempObjs: any = {};
    if (arrs.length) {
      tempObjs = arrs.find(item => item[idKey] == keyVal);
    }

    return tempObjs?.name || '-';
  }

  // 跟进
  showFollowModal(item: any) {
    this.initParams.relationInformation = item.id;
    this.followUpRef.isModelVisible = true;
  }
}
